<?php
namespace WXAPI\Controller;


use Think\Controller;
use Think\Log;


class PayController extends Controller
{
    public $orgid = '660701052513W17';
    public $cusid = '564701052516SQ4';
    public $cusidH5 = '660701052513W16';
    public $appid = '00363825';
    public $sub_appid = 'wxa924b897c5f17a84';
    public $privateKey = 'MIIEowIBAAKCAQEAwpim7IsBFdNOAVtNOd6HGeycKs5MY652QwjhDT8thQyhbhrSnuqqTQw9tOjF35jsvBTcSCEneGzy3rrE+vWJZ3l2afiv1nd3xG4XDEhij3IHCf2IkZwB09FIruftOffYM4VVZDpS46FKWzZMoxXkOdrLCZj5PdHXNbJapfgrL5VcqKtuImysBXDJbVmj1GIFPHhKQQZR0eLLAVlIlTH+CygGYCh+bf0Y1dda0aqhFPAmOq2QsR4YChcj+h5MjUnLqKggaiGOo+PIJFE4m6DxPrfcz7IKcidX7mSx8+PiFwLepudoVQerj9XlmR6w8yAXQkFQMMHnaRN+nWo/yIJzrQIDAQABAoIBAAcTY+Zv+38eqtRzzHARPlpb9yW7UJ3DRzuSxBQmOvJ+jhQh14y9vamFi2zble5Wci04mPXqdrPzSjV9FxKFARUJHpwl1cb3mxxCYIYqz6Klo8niNSgOQya/kmQBvOeBspPVAlDdqgvq3nhIlirL7fuIkB9uN4ne6nNiY9drGa7mMDfU/2QJwUadjxcZqfxxMsuemf4eKSr+bcLMaojqh4e2Aw6qAX0H3nIsq3I11Sim63/x3ONKABYJYj+pdC55INaDr6rntASHJKd+3N9i2gMYBpjnea27zFGYjYBBDkE4jJqPdskIMzfE+PhYyLIP42WddiPl3igdpW3qrYB0i6UCgYEA4Xg7SNDt1Q9ohhSQeniKmGFSFGn9e1Ko0lmeGjDfFsB2EWIKE3uYCthuFwjm/c0vTafO8V/1h7IuQUV5A4jDPluO82GHTdXzXiqqHEwNIa4lDNlqYGX9uHvKRFZrD6HEz3a9ofNVkaqKoQTlGhQRI1CzvL31X2cas/C2datEXwMCgYEA3PI23OiF5WyK7Tn6/6pZ7Jtm7GO/iqLvjOGCGfHoEo8s/Iwhn8wctGP9/EAWGkINGnD9r9g0/DJd83WeGrlmgU7CyNj457jds7WYdfx1QjIj+vDLF9DrM6fLMJ3zBSJUUNCLmrZ1KbDZUK8buEw/4/1+IfddH3t+X4JBw4v+y48CgYAxYRSSyPcdb2dz3fMab2XjI4VHZUMXjC3fC7N9hvCE2hfBjNgqFiphTa8mqlN0iEhw2GyRHnP2iQZqUx3CsWQZNxIiqVxppo7LM8rXsaw6kRoaK0+J1yxvB+VvfAGshcBFs3qqilFWOqRryVenk3eBZX5Hus6PW1RUzkYXlS+/IwKBgQCi3XStkEUq4cDir2uizDqvG7pZpAmMMyDrs0tIvrW4AIxDuTQL69R48IBHUiI4xtmL1SBbX79m6+WvUdLylhnGVX1lufJ4NSBPmRvCVQ9GdVlqX9cFPj4x/Izd0IBUF4MZczCFIdvpmHAIdpuzVZl/ANvaQ9IEI+76jjTV5TszZwKBgGYRTfLcpb0l14X2T4HgWHtie+XR0keAxi0qapnJGc6YfpAhGxMtbXIOeRKRgbbE/gFzYeNIgnFBqwo85578HNRoHYlXlBhiB25fLtrR6J4swEoiDHO98setqBUzRCMLXFv0k0o22RuOOvDHm0Tr6Pj0Deae7vcROJkyImjPVaz8';
    public $publicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwpim7IsBFdNOAVtNOd6HGeycKs5MY652QwjhDT8thQyhbhrSnuqqTQw9tOjF35jsvBTcSCEneGzy3rrE+vWJZ3l2afiv1nd3xG4XDEhij3IHCf2IkZwB09FIruftOffYM4VVZDpS46FKWzZMoxXkOdrLCZj5PdHXNbJapfgrL5VcqKtuImysBXDJbVmj1GIFPHhKQQZR0eLLAVlIlTH+CygGYCh+bf0Y1dda0aqhFPAmOq2QsR4YChcj+h5MjUnLqKggaiGOo+PIJFE4m6DxPrfcz7IKcidX7mSx8+PiFwLepudoVQerj9XlmR6w8yAXQkFQMMHnaRN+nWo/yIJzrQIDAQAB';

    public function payApp($master_order_sn,$return_id,$user_money)
    {
        $notify_url = SITE_URL.'/WXAPI/Pay/callback';
        $version = "12";
        $apiUrl = 'https://vsp.allinpay.com/apiweb/unitorder/nativepay';

        $orders = M('order')->where(['pay_master_order_sn'=>$master_order_sn,'pay_status'=>0])->select();

        $return_sum = 0;
        if($return_id){
            $return_sum = M('return_goods')->field('SUM((member_goods_price*goods_num+yijia)) as sum')->where(['id'=>['in',$return_id]])->find();
            $return_sum = round($return_sum['sum'],2);
        }

        $yingshou = 0;
        $coupon_price = 0;
        foreach ($orders as $order){
            $yingshou+= ($order['order_amount'] + $order['yijia_heji']);
            $coupon_price+= $order['coupon_price'];
        }
        $old_trxamt = sanweis($yingshou);
        $trxamt = sanweis($yingshou-$return_sum-$user_money); //减去退货再减余额


        if($trxamt <= 0) {//当付款金额和退款金额相等时或负数，直接支付成功

            update_pay_status((string)$master_order_sn, $master_order_sn,true);
            if($return_id){
                M('return_goods')->where(['id' => ['in', $return_id]])->save(['master_order_sn' => (string)$master_order_sn]);

                if($trxamt == 0){
                    //退积分
                    $return = M('return_goods')->where(['id'=>['in',$return_id]])->select();
                    foreach ($return as $item){
                        accountLog($item['user_id'],0,$item['integral'],"订单退货，退回{$item['integral']}工分");
                    }
                }
            }

            if($trxamt < 0){ //付款金额小于退货金额需要记录日志并增加会员余额
                $user_id = $orders[0]['user_id'];
                $log = [
                    'master_order_sn' => (string)$master_order_sn,
                    'user_id' => $user_id,
                    'money' => abs($trxamt),
                    'create_time' => time(),
                    'status' => 0,
                ];

                M('pay_deduct_log')->add($log);
                $desc = "支付单号{$master_order_sn}中退货抵扣完成剩余金额：￥".abs($trxamt)."元";
                accountLog($user_id,abs($trxamt),0,$desc);
            }
            $res = [
                'result_code' => 'success',
                'result_msg' => '支付成功',
                'trxamt' => $trxamt,
                'pay_url'=>'',
                'pay_status' => 1,
            ];
            return $res;
        }


        // 获取当前时间并加上 24 小时，然后格式化为 yyyyMMddHHmmss
        $expireTime = (new \DateTime())->modify('+24 hours')->format('YmdHis');

        $unireqsn = $master_order_sn;
        $body = '货款应付￥'.$old_trxamt.' 退货￥'.sanweis($return_sum).' 使用余额￥'.sanweis($user_money).' 实付￥'.sanweis($trxamt);
        $param=
            [
                "version"=>$version,
                "orgid"=>$this->orgid,
                "cusid"=>$this->cusidH5,
                "appid"=>$this->appid,
                "trxamt"=>(String)($trxamt*100),
                "reqsn"=>$unireqsn,
                "notify_url"=>$notify_url,
                "body"=>$body,
                "randomstr"=>(String)rand(1000,9999),
                "signtype"=>'RSA',
                "expiretime"=>$expireTime,
                "sign"=>'',
            ];


        $sign = $this->Sign($param);
        $param['sign'] = $sign;

        $res = json_decode(self::http_post($apiUrl,$param,false), true);


        $res['trxamt'] = $trxamt;
        $res['pay_status'] = 0;
        M('pay_merge_log')->where(['master_order_sn'=>$master_order_sn])->save(['param'=>json_encode($param),'result'=>json_encode($res),'user_money'=>$user_money]);
        if (!empty($res) && $res['retcode'] == 'SUCCESS') {
            return $res;
        }
    }


    /**
     * 小程序支付
     * @param $master_order_sn
     * @param $return_id
     * @return mixed|void
     */
    public function payHFivePay($master_order_sn,$return_id,$user_money,$order_id = "")
    {
        $notify_url = SITE_URL.'/WXAPI/pay/callback';
        $apiUrl = 'https://vsp.allinpay.com/apiweb/unitorder/pay';
        $orders = M('order')->where(['pay_master_order_sn'=>$master_order_sn,'pay_status'=>0])->select();
        $return_sum = 0;
        if($return_id){
            $return_sum = M('return_goods')->field('SUM((member_goods_price*goods_num+yijia)) as sum')->where(['id'=>['in',$return_id]])->find();
            $return_sum = round($return_sum['sum'],2);
        }

        $yingshou = 0;
        $coupon_price = 0;
        foreach ($orders as $order){
            $yingshou+= ($order['order_amount'] + $order['yijia_heji']);
            $coupon_price+= $order['coupon_price'];
        }
        $old_trxamt = sanweis($yingshou);
        $trxamt = $yingshou-$return_sum-$user_money; //减去退货再减余额
        $version = "11";
        $unireqsn = $master_order_sn;
        $body = '货款应付￥'.$old_trxamt.' 退货￥'.sanweis($return_sum).' 使用余额￥'.sanweis($user_money).' 实付￥'.sanweis($trxamt);



        $param=
            [
                "version"=>$version,
                "orgid"=>$this->orgid,
                "cusid"=>$this->cusid,
                "appid"=>$this->appid,
                "trxamt"=>$trxamt*100,
                "reqsn"=>$unireqsn,
                "notify_url"=>$notify_url,
                "body"=>$body,
                "paytype"=>'W11',
                "randomstr"=>(String)rand(1000,9999),
                "validtime"=>1440,
                "acct"=>$order_id,
                "sub_appid"=>$this->sub_appid,
                "signtype"=>'RSA',
                "sign"=>'',
            ];


        $sign = $this->Sign($param);
        $param['sign'] = $sign;

        $res = json_decode(self::http_post($apiUrl,$param,false), true);
        $res['trxamt'] = $trxamt;
        M('pay_merge_log')->where(['master_order_sn'=>$master_order_sn])->save(['param'=>json_encode($param),'result'=>json_encode($res),'result_code'=>$res['retcode'],'user_money'=>$user_money]);
        //返回参数格式设计
        if (!empty($res) && $res['retcode'] == 'SUCCESS') {
            return $res;
        }
    }


    /**
     * 小程序支付
     * @param $master_order_sn
     * @param $return_id
     * @return mixed|void
     */
    public function payMiniPay($master_order_sn,$open_id="")
    {
        $notify_url = SITE_URL.'/WXAPI/pay/callback';
        $apiUrl = 'https://vsp.allinpay.com/apiweb/unitorder/pay';
        $orders = M('order')->where(['pay_master_order_sn'=>$master_order_sn,'pay_status'=>0])->select();

        $yingshou = 0;
        foreach ($orders as $order){
            $yingshou+= ($order['order_amount'] + $order['yijia_heji']);
        }

        $trxamt = $yingshou*100; //减去退货再减余额


        $version = "11";
        $unireqsn = $master_order_sn;
        $body = '实付￥'.$trxamt;


        $param=
            [
                "version"=>$version,
                "cusid"=>$this->cusid,
                "appid"=>$this->appid,
                "trxamt"=>$trxamt,
                "reqsn"=>$unireqsn,
                "notify_url"=>$notify_url,
                "body"=>$body,
                "paytype"=>'W06',
                "randomstr"=>(String)rand(1000,9999),
                "validtime"=>1440,
                "acct"=>$open_id,
                "sub_appid"=>$this->sub_appid,
                "signtype"=>'RSA',
                "sign"=>'',
            ];


        $sign = $this->Sign($param);
        $param['sign'] = $sign;


        $res = json_decode(self::http_post($apiUrl,$param,false), true);
        M('pay_merge_log')->where(['master_order_sn'=>$master_order_sn])->save(['param'=>json_encode($param),'result'=>json_encode($res),'result_code'=>$res['result_code']]);
        //返回参数格式设计
        if (!empty($res) && $res['retcode'] == 'SUCCESS') {
            return $res;
        }
    }

    public function checkPayStatus($order)
    {

        $apiUrl = 'https://vsp.allinpay.com/apiweb/tranx/query';
        $version = "12";
        $unireqsn = $order['order_sn'];

        $param=
            [
                "version"=>$version,
                "cusid"=>$this->cusid,
                "appid"=>$this->appid,
                "reqsn"=>$unireqsn,
                "randomstr"=>(String)rand(1000,9999),
                "signtype"=>'RSA',
                "sign"=>'',
            ];


        $sign = $this->Sign($param);
        $param['sign'] = $sign;
        $res = json_decode(self::http_post($apiUrl,$param,false), true);
        return $res;
    }


    public function Sign(array $array){
        ksort($array);
        $bufSignSrc = $this->ToUrlParams($array);
        $private_key=$this->privateKey;
        $private_key = chunk_split($private_key , 64, "\n");
        $key = "-----BEGIN RSA PRIVATE KEY-----\n".wordwrap($private_key)."-----END RSA PRIVATE KEY-----";
        //   echo $key;
        if(openssl_sign($bufSignSrc, $signature, $key )){
        }else{
            echo 'sign fail';
        }
        $sign = base64_encode($signature);//加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
        return $sign;

    }

    public  function ToUrlParams(array $array)
    {
        $buff = "";
        foreach ($array as $k => $v)
        {
            if($v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }


    public function ValidSign(array $array){
        $sign =$array['sign'];
        unset($array['sign']);
        ksort($array);
        $bufSignSrc = $this->ToUrlParams($array);
        $public_key=$this->publicKey;
        $public_key = chunk_split($public_key , 64, "\n");
        $key = "-----BEGIN PUBLIC KEY-----\n$public_key-----END PUBLIC KEY-----\n";
        $result= openssl_verify($bufSignSrc,base64_decode($sign), $key );
        return $result;
    }


    /**
     * 退款申请
     * @param $returnOrder
     */
    public function returnOrder($returnOrder)
    {
        $order = M('order')->where(['order_id'=>$returnOrder['order_id']])->find();
        if($order && $order['pay_status'] == 1){
            $apiUrl = 'https://vsp.allinpay.com/apiweb/tranx/refund';
            $price = sanweis($returnOrder['member_goods_price'] * $returnOrder['goods_num'] ) * 100;
            $param=
                [
                    "cusid"=>$order['cusid'],
                    "orgid"=>$this->orgid,
                    "appid"=>$this->appid,
                    "trxamt"=>(String)$price,
                    "reqsn"=>$returnOrder['return_order_sn'],
                    "oldtrxid"=>$order['pay_no'],
                    "randomstr"=>(String)rand(1000,9999),
                    "signtype"=>'RSA',
                    "sign"=>'',
                ];


            $sign = $this->Sign($param);
            $param['sign'] = $sign;
            $res = httpRequest($apiUrl,'POST',$param,'');

            $res = json_decode($res, true);

            Log::record(json_encode($res), 'DEBUG');
            M('return_pay_log')->add(['add_time'=>date('Y-m-d H:i:s',time()),'order_sn'=>'return_goods_'.$returnOrder['id'],'param'=>json_encode($param),'result'=>json_encode($res),'result_code'=>$res['retcode'],'pay_code'=>'weixin']);
            //返回参数格式设计
            if (!empty($res) && $res['retcode'] == 'SUCCESS') {
                M('return_goods')->where(['id'=>$returnOrder['id']])->save(['pay_status'=>2,'out_refund_no'=>$res['trxid']]);
                return ['code'=>200,'msg'=>'退款申请成功'];
            }else{
                return ['code'=>300,'msg'=>'退款申请失败'];
            }

        }
    }


    /**
     * 支付反馈
     */
    public function callback()
    {
        $result = I('');
        Log::record(json_encode(I('')), 'DEBUG');

//        $result = '{"code":0,"msg":"成功","result":"{\"fee\":20,\"payment\":\"WXPAY\",\"body\":\"好多多商城\",\"status\":100,\"attach\":\"\",\"mch_id\":\"KP10010393\",\"pay_no\":\"600581089599226592\",\"out_trade_no\":\"202306302331414548\",\"transaction_id\":\"4200001847202306306799152893\",\"channel_transaction_id\":\"33202306300633972774100\",\"origin_fee\":20,\"received_fee\":20,\"user_pay_fee\":20,\"discount\":{\"mdiscount_fee\":0,\"ydiscount_fee\":0,\"pdiscount_fee\":0,\"m_discount_fee\":0,\"y_discount_fee\":0,\"p_discount_fee\":0},\"pay_time\":\"2023-06-30 23:39:39\",\"pay_finish_time\":\"2023-06-30 23:39:46\"}","sign":"382F41E50806D038D5B7B4914AAB5B4C","sign_type":"MD5"}';
        if (!empty($result)) {
            if ($result && $result['trxstatus'] == '0000') {
                M('pay_callback_log')->add(['callback_text'=>json_encode($result),'create_time'=>date('Y-m-d H:i:s',time())]);
                update_pay_status($result['cusorderid'],$result['trxid'],$result['chnltrxid'],$result['cusid']);

                $pay_merge_log = M('pay_merge_log')->where(['master_order_sn'=>(String)$result['cusorderid']])->find();

                if($pay_merge_log){
                    M('pay_merge_log')->where(['master_order_sn'=>(String)$result['orderId']])->save(['pay_status'=>1]);
                    $order_list = M('order')->where(['order_id'=>['in',$pay_merge_log['order_sn']]])->select();

                    //处理退货关联
                    M('return_goods')->where(['id'=>['in',$pay_merge_log['return_id']]])->save(['master_order_sn'=>(String)$result['orderId']]);

                    $order_sn = [];
                    $driver_mobile = '';
                    foreach ($order_list as $item){
                        $order_sn[] = $item['order_sn'];
                        $driver_id = $item['driver_id'];
                        $driver_mobile = M('users')->where(['user_id'=>$driver_id])->getField('mobile');
                    }
                    $mqtt_url = 'https://iot.vyxjj.com/api/app/shop/pay/success';
                    httpRequest($mqtt_url,'POST',['driver_mobile'=>$driver_mobile,'platform'=>'bmd','order_sn'=>join(',',$order_sn)]);

                    echo "SUCCESS";
                    return;
                    die;
                }else{
                    $order = M('order')->where(['order_sn'=>(String)$result['orderId']])->find();
                    if($order){
                        $pay_now_log = M('pay_now_log')->where(['order_sn'=>$order['order_id']])->find();
                        if($pay_now_log){
                            M('pay_now_log')->where(['order_sn'=>$order['order_id']])->save(['pay_status'=>1]);
                        }
                    }

                    echo "SUCCESS";
                    return;
                    die;
                }

            }
        }

    }


    /**
     * 退款反馈
     */
    public function returnCallback()
    {
        $result = I('');
        Log::record(json_encode(I('')), 'DEBUG');

        if (!empty($result)) {

            if ($result && $result['result_code'] == 'SUCCESS') {
                M('return_goods')->where(['out_refund_no'=>$result['out_refund_no']])->save(['pay_status'=>2]);
            }
            M('return_log')->add(['out_refund_no'=>$result['out_refund_no'],'result'=>json_encode($result)]);
            echo "SUCCESS";
            return;
            die;
        }

    }


    public function cs()
    {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        $randsi = date("YmdHis") . rand(1000, 9999);
        $out_trade_no = get_order_sn();
        $array=
            [
                "mch_id"=>$this->mchId,
                "timestamp"=>time(),
                "nonce_str"=>$randsi,
                "sign_type"=>'MD5',
                "content"=>json_encode([
                    'out_trade_no'=>$out_trade_no,
                    'account_type'=>1,
                    'account'=>'6228480099651706972',
                    'account_name'=>'邵富文',
                    'bank_name'=>'中国农业银行',
                    'amount'=>'10',
                ],JSON_UNESCAPED_UNICODE),
            ];
        foreach ($array as $k => $v)
        {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $buff = "";
        ksort($Parameters);
        foreach ($Parameters as $k => $v) {
            $buff .= $k . "=" . $v . "&";
        }
        $String = '';
        if (strlen($buff) > 0) {
            $String = substr($buff, 0, strlen($buff) - 1);
        }
        //签名步骤三：MD5加密
        $String = md5($String);
        //签名步骤四：所有字符转为大写
        $strings = strtoupper($String);
        $array['sign'] = $strings;

        $res = json_decode(self::http_post('https://pay.kudianvip.com/openapi/pay/fund/accountPaid',json_encode($array)), true);
        print_r($res);
    }




    /**
     * 使用http_post提交
     * @param $url
     * @param $params
     * @param bool $contentType
     * @return bool|mixed|string
     */
    protected function http_post($url, $params, $contentType=true)
    {

        if (function_exists('curl_init')){
            // curl方式
            $oCurl = curl_init();
            if (stripos($url, 'https://') !== FALSE){
                curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
            }
            $string = $params;
            if (is_array($params)){
                $aPOST = array();
                foreach ($params as $key => $val) {
                    $aPOST[] = $key . '=' . urlencode($val);
                }
                $string = join('&', $aPOST);
            }
            curl_setopt($oCurl, CURLOPT_URL, $url);
            curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($oCurl, CURLOPT_POST, TRUE);
            //$contentType json处理
            if($contentType){
                $headers = array(
                    "Content-type: application/json;charset='utf-8'",
                );

                curl_setopt($oCurl, CURLOPT_HTTPHEADER, $headers);
                curl_setopt($oCurl, CURLOPT_POSTFIELDS, $params);
            }else{
                curl_setopt($oCurl, CURLOPT_POSTFIELDS, $string);
            }
            $response = curl_exec($oCurl);
            curl_close($oCurl);
            return $response;
        } elseif (function_exists('stream_context_create')) {
            // php5.3以上
            $opts = array(
                'http' => array(
                    'method' => 'POST',
                    'header' => 'Content-type: application/x-www-form-urlencoded',
                    'content' => http_build_query($params),
                )
            );
            $_opts = stream_context_get_params(stream_context_get_default());
            $context = stream_context_create(array_merge_recursive($_opts['options'], $opts));
            return file_get_contents($url, false, $context);
        }else{
            return FALSE;
        }
    }



    function get_client_ip() {
        $ip = '';
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $ip = trim($ips[0]);
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $ip;
    }

}